package cn.fbs.service.core;

import cn.fbs.dao.dm.*;
import cn.fbs.enums.MediaEnum;
import cn.fbs.model.*;
import cn.fbs.service.AssignService;
import cn.fbs.service.UploadService;
import cn.fbs.util.MyZipUtil;
import lombok.extern.java.Log;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.util.Date;
import java.util.List;

@Service
@Log
public class ExtractService {
    @Value(("${data.upload.doestUrl}"))
    private String dataUploadDoestUrl;

    @Value(("${video.upload.doestUrl}"))
    private String videoUploadDoestUrl;

    @Value(("${image.upload.doestUrl}"))
    private String imageUploadDoestUrl;

    @Value("${resource.locations}")
    private String resourceLocations;

    @Value(("${compressRatio}"))
    private Integer compressRatio;

    @Value(("${maxJoinNum}"))
    private int maxJoinNum;

    @Autowired
    private DMImageInfoMapper imageInfoMapper;
    @Autowired private DMVideoInfoMapper videoInfoMapper;
    @Autowired private DMDataInfoMapper dataInfoMapper;
    @Autowired private DMBusinessAtlasInfoMapper atlasMidTMapper;
    @Autowired private DMNewTargetMapper targetMapper;
    @Autowired private DMLabelGroupInfoMapper lableMapper;
    @Autowired private DMCodeCategoryTypeMapper categoryTypeMapper;
    @Autowired private DMQbCategoryConnectionMapper connectionMapper;

    @Autowired private UploadService uploadService;
    @Autowired private AssignService assignService;




    @Transactional(rollbackFor = Exception.class)
    public String extractImage(MultipartFile file, String userName) throws Exception {
        int successNum = 0;
        int existNum = 0;
        String xmlDir = unZipData(file,"image");
        Document document = readerImageXml(xmlDir);
        /**
         * 获取到集合信息
         */
        Element rootElement = document.getRootElement();
        String name = rootElement.attributeValue("name");
        String taskName = null;
        if (StringUtils.isNotEmpty(name)) {
            taskName = name;
        }
        List<Element> objectElements = rootElement.elements("Object");
        for (int i = 0; i < objectElements.size(); i++) {
            Element objectElement = objectElements.get(i);
            /**
             * 处理文件信息
             */
            TImageInfo imageInfo = assignService.xmlGiveImageInfo(objectElement, taskName, xmlDir);
            /**
             * 保存图像信息
             */
            Integer count = imageInfoMapper.countByName(imageInfo.getFileName());
            if (count == 0) {
                imageInfo.setOperator(userName);
                imageInfoMapper.insertImage(imageInfo);
                ++successNum;
            } else {
                ++existNum;
                continue;
            }
            /**
             * 处理标签信息
             */
//            Integer messageId = imageInfoMapper.selectIdByFileName(imageInfo.getFileName());
            Long id = imageInfo.getId();
            saveCategoryInfo(objectElement.elements(), id.intValue(), MediaEnum.IMAGE.getIndex());
        }
        if (existNum != 0) {
            System.out.println("extractImage_4");
            return "200,提取成功" + successNum + "条数据，已存在" + existNum + "条数据";
        }
        if (successNum == 0) {
            System.out.println("extractImage_5");
            return "500,提取失败，文件内容已存在";
        }
        System.out.println("extractImage_6end");
        return "200,提取成功" + successNum + "条数据";
    }

    @Transactional(rollbackFor = Exception.class)
    public String extractVideo(MultipartFile file,String userName) throws Exception {
        int successNum = 0;
        int existNum = 0;
        String xmlDir = unZipData(file,"video");
        Document document = readerVideoXml(xmlDir);

        /**
         * 获取到集合信息
         */
        Element rootElement = document.getRootElement();
        String name = rootElement.attributeValue("name");
        String taskName = null;
        if (StringUtils.isNotEmpty(name)) {
            System.out.println("extractVideo_1");
            taskName = name;
        }
        List<Element> objectElements = rootElement.elements("Object");
        for (int i = 0; i < objectElements.size(); i++) {
            Element objectElement = objectElements.get(i);
            /**
             * 处理文件信息
             */
            TVideoInfo videoInfo = assignService.xmlGiveVideoInfo(objectElement, taskName, xmlDir);
            /**
             * 保存图像信息--保存之前判断是否已存在，若已存在，则不进行保存
             */
            Integer count = videoInfoMapper.countByName(videoInfo.getFileName());
            if (count == 0) {
                System.out.println("extractVideo_2");

                videoInfo.setOperator(userName);
                videoInfoMapper.insertVideo(videoInfo);
                ++successNum;
            } else {
                System.out.println("extractVideo_3");
                ++existNum;
                continue;
            }
            /**
             * 处理标签信息
             */
//            Integer messageId = videoInfoMapper.selectIdByFileName(imageInfo.getFileName());
            Long id = videoInfo.getId();
            saveCategoryInfo(objectElement.elements(), id.intValue(), MediaEnum.VIDEO.getIndex());
        }
        if (existNum != 0) {
            System.out.println("extractVideo_4");
            return "200,提取成功" + successNum + "条数据，已存在" + existNum + "条数据";
        }
        if (successNum == 0) {
            System.out.println("extractVideo_5");
            return "500,提取失败，文件内容已存在";
        }
        System.out.println("extractVideo_6end");
        return "200,提取成功" + successNum + "条数据";
    }
    public String unZipData(MultipartFile file,String fileType) {
        /**
         * 上传解压文件，并获取到xml文件
         */

        String zipPath = uploadService.uploadXml(file,fileType);
        if (zipPath.startsWith("500")) {
            return zipPath;
        }
        String xmlDir = zipPath.substring(0, zipPath.lastIndexOf("."));
        try {
            MyZipUtil.commonDeCompress(zipPath, xmlDir, false);
        } catch (Exception exception) {
            exception.printStackTrace();
            return "500,文件格式不正确";
        }
        return xmlDir;
    }

    private Document readerImageXml(String xmlDir) throws Exception {
        File xmlDirFile = new File(xmlDir);
        String[] list = xmlDirFile.list();
        String xmlPath = "";
        for (String subPath : list) {
            if (!subPath.contains(".")) {
                throw new Exception();
            }
            if (subPath.endsWith("mp4")) {
                throw new Exception();
            }
            if (subPath.endsWith("xml")) {
                xmlPath = subPath;
            }
        }
        SAXReader reader = new SAXReader();
        FileInputStream fileInputStream = new FileInputStream(xmlDir + "/" + xmlPath);
        Document document = reader.read(fileInputStream);
        fileInputStream.close();
        return document;
    }

    void saveCategoryInfo(List<Element> elements, Integer messageId, Integer dataType) {
        for (Element element : elements) {
            if (!element.getName().equals("包名")) {
                /**
                 * 先判断标签组和标签是否存在，如果不存在，则自动入库，如果存在则将关联信息进行保存--用户信息暂时写死
                 */
                TLabelGroupInfo labelGroupInfo = lableMapper.selectByName(element.getName());
                if (labelGroupInfo == null) {
                    labelGroupInfo = new TLabelGroupInfo();
                    labelGroupInfo.setCreateDate(new Date());
                    labelGroupInfo.setIsInherent((byte) 0);
                    labelGroupInfo.setName(element.getName());
                    lableMapper.insert(labelGroupInfo);
                    labelGroupInfo = lableMapper.selectByName(element.getName());
                }
                String groupId = labelGroupInfo.getId();
                /**
                 * 不能只依靠标签名去查询，不同标签组下可能会有同样名字的标签
                 */
                TCodeCategoryType categoryType = categoryTypeMapper.selectByNameAndLabel(element.getText(), element.getName());
                if (categoryType == null) {
                    categoryType = new TCodeCategoryType();
                    categoryType.setGroupId(groupId);
                    categoryType.setCategoryName(element.getText());
                    categoryType.setCreateDate(new Date());
                    categoryTypeMapper.insert(categoryType);
                }
                Integer categoryId = categoryType.getId();
                TQbCategoryConnection connection = new TQbCategoryConnection();
                connection.setMessageId(Long.parseLong(messageId.toString()));
                connection.setConnectionType(dataType);
                connection.setCategoryId(Long.parseLong(categoryId.toString()));
                connection.setUserId(1L);
                connectionMapper.insert(connection);
            }
        }
    }


    private Document readerVideoXml(String xmlDir) throws Exception {
        File xmlDirFile = new File(xmlDir);
        String[] list = xmlDirFile.list();
        String xmlPath = "";
        for (String subPath : list) {
            if (!subPath.contains(".")) {
                throw new Exception();
            }
            if (subPath.endsWith("jpg") || subPath.endsWith("png")) {
                throw new Exception();
            }
            if (subPath.endsWith("xml")) {
                xmlPath = subPath;
            }
        }
        SAXReader reader = new SAXReader();
        FileInputStream fileInputStream = new FileInputStream(xmlDir + "/" + xmlPath);
        Document document = reader.read(fileInputStream);
        fileInputStream.close();
        return document;
    }
}
